﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TcpSyncServer
{
    public partial class Form1 : Form
    {
        private IPAddress localAddress;
        private const int port = 5656;
        private TcpListener tcpListener;
        private TcpClient tcpClient;
        private NetworkStream networkStream;
        private BinaryReader binaryReader;
        private BinaryWriter binaryWriter;

        // 声明委托
        private delegate void ShowMessage(string str);
        private ShowMessage showMessage;
        private delegate void ShowStatus(string str);
        private ShowStatus showStatus;

        private delegate void ShowProgress(int proc);
        private ShowProgress showProgress;
        private delegate void ResetText();
        private ResetText resetText;

        public Form1()
        {
            InitializeComponent();
            showMessage = new ShowMessage(ShwMsgForView);
            showStatus = new ShowStatus(ShwStatusInfo);
            showProgress = new ShowProgress(ShwProgressProc);
            resetText = new ResetText(ResetMsgText);
        }

        /// <summary>
        /// 显示消息
        /// </summary>
        private void ShwMsgForView(string str)
        {
            str = System.DateTime.Now.ToString() + Environment.NewLine + Environment.NewLine;
            int txtGetMsgLength = this.richTextBox1.Text.Length;
            this.richTextBox2.AppendText(str);
            this.richTextBox2.Select(txtGetMsgLength, str.Length - Environment.NewLine.Length * 2 - str.Length);
            this.richTextBox2.SelectionColor = Color.Red;
            this.richTextBox2.ScrollToCaret();
        }

        /// <summary>
        ///  显示状态
        /// </summary>
        /// <param name="str"></param>
        private void ShwStatusInfo(string str)
        {
            toolStripStatusLabel1.Text = str;
        }

        /// <summary>
        /// 显示进度
        /// </summary>
        /// <param name="proc"></param>
        private void ShwProgressProc(int proc)
        {
            toolStripProgressBar1.Value = proc;
        }

        /// <summary>
        /// 重置文本
        /// </summary>
        private void ResetMsgText()
        {
            richTextBox2.Text = " ";
            richTextBox2.Focus();
        }

        /// <summary>
        /// 获取客户端连接
        /// </summary>
        private void AcceptClientConnect()
        {
            statusStrip1.Invoke(showStatus, "[" + localAddress + ":" + port + "]监听...");
            DateTime dateTime = DateTime.Now;
            while (dateTime.AddSeconds(1) > dateTime)
            {
                try
                {
                    statusStrip1.Invoke(showStatus, "等待连接...");
                    statusStrip1.Invoke(showProgress, 1);
                    // 获取客户端连接对象,开启监听
                    tcpClient = tcpListener.AcceptTcpClient();
                    statusStrip1.Invoke(showProgress, 100);
                    // 获取客户端连接对象之后收发数据
                    if (tcpClient != null)
                    {
                        statusStrip1.Invoke(showStatus, "接受了一个请求");
                        networkStream = tcpClient.GetStream();
                        binaryReader = new BinaryReader(networkStream);
                        binaryWriter = new BinaryWriter(networkStream);
                    }
                }
                catch
                {
                    statusStrip1.Invoke(showStatus, "停止监听");
                    if (tcpListener != null)
                    {
                        tcpListener.Stop();
                    }
                    DateTime dateTime1 = DateTime.Now;
                    while (dateTime1.AddSeconds(1) > DateTime.Now)
                    { }
                    statusStrip1.Invoke(showProgress, 0);
                    statusStrip1.Invoke(showStatus, "就绪");
                }
            }
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        private void ReceiveMessage()
        {
            statusStrip1.Invoke(showStatus, "接收中...");
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    string rcvMsgStr = binaryReader.ReadString();
                    statusStrip1.Invoke(showProgress, i + 1);
                    if (rcvMsgStr != null)
                    {
                        richTextBox2.Invoke(showMessage, rcvMsgStr);
                    }
                }
                catch
                {
                    if (binaryReader != null)
                    {
                        binaryReader.Close();
                    }
                    if (binaryWriter != null)
                    {
                        binaryWriter.Close();
                    }
                    if (tcpClient != null)
                    {
                        tcpClient.Close();
                    }
                    statusStrip1.Invoke(showStatus, "连接断开");
                    statusStrip1.Invoke(showProgress, 0);
                    DateTime dateTime = DateTime.Now;
                    while (dateTime.AddSeconds(2) > DateTime.Now)
                    {
                    }
                    // 开启一个监听行程再次监听客户端的连接
                    Thread thread = new Thread(new ThreadStart(AcceptClientConnect));
                    thread.Start();
                    break;
                }
            }
            statusStrip1.Invoke(showStatus, "接收了" + 5 + "条消息...");
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="state"></param>
        private void SendMessage(object state)
        {
            statusStrip1.Invoke(showStatus, "正在发送");
            for (int i = 0; i < 5; i++)
            {
                try
                {
                    binaryWriter.Write(state.ToString());
                    statusStrip1.Invoke(showProgress, i + 1);
                    DateTime dateTime = DateTime.Now;
                    while (dateTime.AddSeconds(5) > DateTime.Now) { }
                    binaryWriter.Flush();
                }
                catch
                {
                    if (binaryReader != null)
                    {
                        binaryReader.Close();
                    }
                    if (binaryWriter != null)
                    {
                        binaryWriter.Close();
                    }
                    if (tcpClient != null)
                    {
                        tcpClient.Close();
                    }
                    statusStrip1.Invoke(showStatus, "连接断开!");
                    statusStrip1.Invoke(showProgress, 0);
                    DateTime dateTime = DateTime.Now;
                    while (dateTime.AddSeconds(2) > DateTime.Now)
                    {
                    }
                    Thread thread = new Thread(new ThreadStart(AcceptClientConnect));
                    thread.Start();
                    break;
                }
            }
            statusStrip1.Invoke(showStatus, "完毕");
            DateTime dateTime1 = DateTime.Now;
            while (dateTime1.AddSeconds(1) > DateTime.Now) { }
            statusStrip1.Invoke(showProgress, 0);
            richTextBox1.Invoke(resetText, null);
        }

        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            toolStripProgressBar1.Maximum = 5;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(ReceiveMessage);
            thread.Start();
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            toolStripProgressBar1.Maximum = 5;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(new ParameterizedThreadStart(SendMessage));
            thread.Start(richTextBox1.Text);
        }

        /// <summary>
        /// 开启监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            IPHostEntry iPHostEntry = Dns.GetHostEntry(Dns.GetHostName());
            localAddress = new IPAddress(iPHostEntry.AddressList[0].Address);
            tcpListener = new TcpListener(localAddress, 5656);
            tcpListener.Start();
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            Thread thread = new Thread(AcceptClientConnect);
            thread.Start();
        }

        /// <summary>
        /// 取消监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (binaryReader != null)
            {
                binaryReader.Close();
            }
            if (binaryWriter != null)
            {
                binaryWriter.Close();
            }
            if (tcpClient != null)
            {
                tcpClient.Close();
            }
            toolStripStatusLabel1.Text = "连接断开";
            toolStripProgressBar1.Maximum = 100;
            toolStripProgressBar1.Value = 0;
            DateTime now = DateTime.Now;
            while (now.AddSeconds(2) > DateTime.Now) { }
            Thread thread = new Thread(AcceptClientConnect);
            thread.Start();

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }


        private void Form1_FormClosing(object sender, FormClosedEventArgs formClosedEventArgs)
        {
            if (binaryReader != null)
            {
                binaryReader.Close();
            }
            if (binaryWriter != null)
            {
                binaryWriter.Close();
            }
            if (tcpClient != null)
            {
                tcpClient.Close();
            }
        }

        private void richTextBox2_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
